package lock.livelock;

import java.math.BigDecimal;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 帐户类 用于演示死锁
 *
 * @author 86155
 * @date 2025/08/16
 */
public class Account {

    /**
     * 账户名称
     */
    private String accountName;

    /**
     * 余额
     */
    private BigDecimal balance;
    /**
     * 锁
     */
    private final Lock lock = new ReentrantLock();

    public Account(String accountName, BigDecimal balance) {
        this.accountName = accountName;
        this.balance = balance;
    }

    public String getAccountName() {
        return accountName;
    }

    public void setAccountName(String accountName) {
        this.accountName = accountName;
    }

    public BigDecimal getBalance() {
        return balance;
    }

    public void setBalance(BigDecimal balance) {
        this.balance = balance;
    }

    void transfer(Account tar, int amt) throws InterruptedException {
        boolean flag = true;

        // 不断尝试加锁两个账户
        while (flag) {
            Random random = new Random();
            if(this.lock.tryLock(random.nextInt(50), TimeUnit.MILLISECONDS)) {
                if (tar.lock.tryLock(random.nextInt(50), TimeUnit.MILLISECONDS)) {
                    // 加锁成功，执行转账
                    setBalance(this.balance.subtract(new BigDecimal(amt)));
                    tar.setBalance( tar.balance.add(new BigDecimal(amt)));
                    System.out.println(Thread.currentThread().getName() + " amt:" + this.balance);
                    // 跳出循环
                    flag = false;
                }
            }

            // 释放锁资源
            try {
                this.lock.unlock();
                tar.lock.unlock();
            } catch (IllegalMonitorStateException e) {

            }

        }
    }
}
